package io.hei.modules.kbms.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.hei.common.utils.AmisCRUDUtils;
import io.hei.common.utils.Excel;
import io.hei.common.utils.PageUtils;
import io.hei.common.utils.Query;
import io.hei.modules.kbms.dao.KbmsArticleMainDao;
import io.hei.modules.kbms.entity.KbmsArticleMainDTO;
import io.hei.modules.kbms.entity.KbmsArticleMainEntity;
import io.hei.modules.kbms.service.KbmsArticleMainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;


@Service("kbmsArticleMainService")
public class KbmsArticleMainServiceImpl extends ServiceImpl<KbmsArticleMainDao, KbmsArticleMainEntity> implements KbmsArticleMainService {

    @Autowired
    private KbmsArticleMainDao kbmsArticleMainDao;

    @Override
    public AmisCRUDUtils selectByParams(KbmsArticleMainDTO kbmsArticleMainDTO, int page, int perPage) {

        // 组装分页参数
        PageHelper.startPage(page, perPage);
        List<Map<String, ?>> maps = kbmsArticleMainDao.selectByParams(kbmsArticleMainDTO);
        PageInfo pageInfo = new PageInfo<>(maps);

        return new AmisCRUDUtils(pageInfo.getTotal(), pageInfo.getList());
    }

    @Override
    public AmisCRUDUtils selectFullText(KbmsArticleMainDTO kbmsArticleMainDTO, int page, int perPage) {

        // 组装分页参数
        PageHelper.startPage(page, perPage);
        List<Map<String, ?>> maps = kbmsArticleMainDao.selectFullText(kbmsArticleMainDTO);
        PageInfo pageInfo = new PageInfo<>(maps);

        return new AmisCRUDUtils(pageInfo.getTotal(), pageInfo.getList());
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<KbmsArticleMainEntity> page = this.page(
                new Query<KbmsArticleMainEntity>().getPage(params),
                new QueryWrapper<KbmsArticleMainEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void export(Map<String, Object> params, HttpServletResponse response) {

        // 初始化OutputStream
        OutputStream output = null;

        int page = (int) params.get("page");
        int perPage = 10;

        KbmsArticleMainDTO kbmsArticleMainDTO = new KbmsArticleMainDTO();

        // 组装分页参数
        PageHelper.startPage(page, perPage);
        List<Map<String, ?>> excelMaps = kbmsArticleMainDao.selectByParams(kbmsArticleMainDTO);
        PageInfo pageInfo = new PageInfo<>(excelMaps);

        // 准备将数据集合封装成Excel对象
        String excelName = "export.xlsx";

        // 可以设置多张表
        ExcelWriter writer = ExcelUtil.getWriter(true);

        // 自定义表格标题栏
        int size = excelMaps.get(0).size();
        writer.merge(size - 1, "文章列表标题");

        // 通过工具类创建writer并且进行别名
        // 别名会重上至下排序，没取别名的则默认排在最前面
        // 这里只是示例，并没全部取别名
//        writer.addHeaderAlias("menuId", "菜单id");
//        writer.addHeaderAlias("menuName", "菜单名");

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除
        writer.setOnlyAlias(false);

        // 准备将对象写入 List
        writer.write(excelMaps, true);

        // 自适应列宽度，数万级或以上数量时性能较慢
        Excel.setSizeColumn(writer.getSheet(), size - 1);

        // 自适应列宽度，仅支持非合并列且中文支持不好
        // writer.autoSizeColumnAll();
        try {
            // 获取输出流
            output = response.getOutputStream();
            response.setHeader("Content-disposition", "attachment;filename=" +
                    URLEncoder.encode(excelName, "UTF-8"));
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            writer.flush(output, true);
            writer.close();
            // 这里可以自行关闭资源或者写一个关闭资源的工具类
            IoUtil.close(output);
        } catch (IOException e) {
            log.error("SysExcelServiceImpl [export] 输出到响应流失败", e);
            e.printStackTrace();
        } finally {
            try {
                if(output != null){
                    output.close();
                }
            } catch (IOException e) {
                log.error("SysExcelServiceImpl [export] 关闭OutputStream失败", e);
                e.printStackTrace();
            }
        }
    }

}
